package driver

import (
	"errors"
	"fmt"
	"log/slog"
	"net"
	"slices"
	"sync"
	"sync/atomic"
	"time"

	"gitee.com/gousing/cache/internal"
	"gitee.com/gousing/cache/storage"
	"github.com/vmihailenco/msgpack/v5"
)

// MemoryCache 内存缓存实例结构体
type MemoryCache struct {
	maxSize         int64          // 缓存空间容量，单位为字节
	maxEntrySize    int64          // 单个缓存项最大数据大小，单位为字节
	cacheShardCount uint32         // 缓存分片数，分片数要求为 2 的幂，默认为128个分片, 如果小于2则设置为2
	cacheShardMask  uint32         // 缓存分片掩码，用于快速定位缓存项所在的分片
	tagShardCount   uint32         // 标签分片数, 分片数要求为 2 的幂，默认为 CacheShardCount/4, 如果小于2则设置为2
	tagShardMask    uint32         // 标签分片掩码，用于快速定位缓存项所在的分片
	defaultExpire   time.Duration  // 全局默认过期时间，默认为0表示永久不过期, 最小为1秒
	shards          []*memoryShard // LRU缓存分片，用于快速查找缓存项
	tagKeys         []*memoryTags  // 标签分片集合(tag=>[]keys), 用于快速查找带有相同标签的缓存项
	keyTags         []*memoryTags  // 标签分片集合(key=>[]tags), 用于快速查找带有相同标签的缓存项
	cleanupInterval time.Duration  // 定时清理过期缓存项的间隔时间，单位为秒, 默认为60秒, 最小为60秒
	cleanupState    atomic.Bool    // 定时清理运行状态
	stopCh          chan struct{}  // 停止定时清理过期缓存项的信号通道
	isClosed        atomic.Bool    // 缓存实例是否已经关闭
	isGlobal        bool           // 是否为全局默认cache
}

// MemoryOptions 缓存配置选项结构体
//   - 关于单个缓存项最大数据大小限制为 MaxSize/CacheShardCount
//   - 如 MaxSize 为 128MB, CacheShardCount 为 128 个分片，则单个缓存项最大数据大小为 128*1024*1024/128 = 1MB
//   - 如 MaxSize 为 64MB, CacheShardCount 为 128 个分片，则单个缓存项最大数据大小为 64*1024*1024/128 = 512KB
//   - 如 MaxSize 为 32MB, CacheShardCount 为 128 个分片，则单个缓存项最大数据大小为 32*1024*1024/128 = 256KB
type MemoryOptions struct {
	MaxSize         int64         // 缓存数据最大空间容量(最大占用内存, 仅包含缓存K/V数据, 不包含缓存结构管理数据)，单位为MB, 默认为 128 MB, 最小为2
	CacheShardCount uint32        // Memory LRU缓存默认的分片数, 分片数要求为 2 的幂（如 2,8,16,32,64,128,256,512,1024,2048）, 默认为 128 个分片，最小为2, 最大为4096
	TagShardCount   uint32        // TAG标签分片数, 分片数要求为 2 的幂，默认为 CacheShardCount/4, 如果小于2则设置为2
	DefaultExpire   time.Duration // 全局默认过期时间，默认为0表示永久不过期(实例生命周期内/长久存储), 最小为1秒, 过期时间是一个近似值，实际过期时间会在 (X-1, X] 秒之间，其中 X 是你设置的过期时间
	CleanupInterval time.Duration // 定时清理过期缓存项的间隔时间，单位为秒, 默认为60秒, 最小为60秒
}

var defaultMemoryOptions = MemoryOptions{
	MaxSize:         128,
	CacheShardCount: 128,
	TagShardCount:   32,
	DefaultExpire:   0,
	CleanupInterval: time.Minute,
}

// NewMemory 创建一个新的 Memcache 实例
//   - maxSize: 缓存的最大大小，单位为MB, 如果设置为0或负数，则默认为128MB。
func NewMemory(ops *MemoryOptions) (*MemoryCache, error) {
	if ops == nil {
		ops = &defaultMemoryOptions
	} else {
		if ops.MaxSize <= 0 {
			ops.MaxSize = 128
		} else if ops.MaxSize < 1 {
			ops.MaxSize = 1
		}
		if ops.CacheShardCount <= 0 {
			ops.CacheShardCount = 128
		} else {
			ops.CacheShardCount = internal.PowerOf2(ops.CacheShardCount)
		}
		if ops.TagShardCount <= 0 {
			ops.TagShardCount = internal.PowerOf2(ops.CacheShardCount / 4)
		} else {
			ops.TagShardCount = internal.PowerOf2(ops.TagShardCount)
		}
		if ops.DefaultExpire <= 0 {
			ops.DefaultExpire = 0
		} else if ops.DefaultExpire < time.Second {
			ops.DefaultExpire = time.Second
		}

		if ops.CleanupInterval < time.Minute {
			ops.CleanupInterval = time.Minute
		}
	}

	c := &MemoryCache{
		maxSize:         ops.MaxSize * 1024 * 1024,                              // 缓存数据容量单位MB转为字节
		maxEntrySize:    ops.MaxSize * 1024 * 1024 / int64(ops.CacheShardCount), // 单个缓存项最大数据大小，单位为字节
		cacheShardCount: ops.CacheShardCount,
		cacheShardMask:  ops.CacheShardCount - 1,
		tagShardCount:   ops.TagShardCount,
		tagShardMask:    ops.TagShardCount - 1,
		shards:          make([]*memoryShard, ops.CacheShardCount),
		tagKeys:         make([]*memoryTags, ops.TagShardCount),
		keyTags:         make([]*memoryTags, ops.TagShardCount),
		defaultExpire:   ops.DefaultExpire,
		cleanupInterval: ops.CleanupInterval,
		stopCh:          make(chan struct{}),
	}
	for i := range c.cacheShardCount {
		c.shards[i] = newMemoryShard(c)
	}
	for i := range c.tagShardCount {
		c.tagKeys[i] = newMemoryTags()
		c.keyTags[i] = newMemoryTags()
	}
	go c.startCleanupExpired(ops.CleanupInterval)
	return c, nil
}

// NewMemoryDefault 创建一个新的 Memcache 实例, 使用默认配置信息
//   - MaxSize:         128 // MB
//   - CacheShardCount: 128
//   - TagShardCount:   32
//   - DefaultExpire:   0
//   - CleanupInterval: time.Minute
func NewMemoryDefault() (*MemoryCache, error) {
	return NewMemory(&defaultMemoryOptions)
}

var _ storage.Storager = (*MemoryCache)(nil)

// startCleanupExpired 启动定时清理过期缓存项的协程
func (c *MemoryCache) startCleanupExpired(interval time.Duration) {
	// 停止之前的清理协程
	if c.cleanupState.CompareAndSwap(true, false) {
		// 触发 c.stopTicker 等待清理协程退出
		c.stopCh <- struct{}{}
	}
	// 启动清理过期缓存项的协程
	if c.cleanupState.CompareAndSwap(false, true) {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()
		var wg sync.WaitGroup
		for {
			select {
			case <-ticker.C:
				// 控制并发数为分片数的三分之一，防止并发过高导致性能下降
				sem := make(chan struct{}, max(c.cacheShardCount/3, 2))
				for _, shard := range c.shards {
					sem <- struct{}{}
					wg.Add(1)
					if !c.cleanupState.Load() {
						wg.Done()
						return
					}
					go func(shard *memoryShard) {
						defer wg.Done()
						defer func() { <-sem }()
						shard.Evict()
					}(shard)
				}
				wg.Wait()
			case <-c.stopCh:
				return
			}
		}
	}
}

// getCacheShard 根据键名获取对应的 LRU 缓存分片
func (c *MemoryCache) getCacheShard(key string) *memoryShard {
	return c.shards[internal.HashFnv32(key)&c.cacheShardMask]
}

// getTagKeysShard 根据 Tag 标签获取对应的 Tag => Keys 集合分片
func (c *MemoryCache) getTagKeysShard(tag string) *memoryTags {
	return c.tagKeys[internal.HashFnv32(tag)&c.tagShardMask]
}

// getKeyTagsShard 根据 Key 键名获取对应的 Key => Tags 集合分片
func (c *MemoryCache) getKeyTagsShard(key string) *memoryTags {
	return c.keyTags[internal.HashFnv32(key)&c.tagShardMask]
}

// getEntryOption 根据 EntryOption 配置信息获取缓存项节点配置信息
func (c *MemoryCache) getEntryOption(opts ...storage.EntryOptions) *storage.EntryOption {
	op := storage.GetEntryOptionsFromPool()
	op.Expire = c.defaultExpire
	// 追加 opts 配置信息, 并覆盖之前的配置信息
	for _, fn := range opts {
		fn(op)
	}
	return op
}

// getEntryOptionWithEntry 根据缓存项节点获取 EntryOption 配置信息, 并以覆盖方式追加 opts 配置
func (c *MemoryCache) getEntryOptionWithEntry(node *memoryEntry, opts ...storage.EntryOptions) *storage.EntryOption {
	op := storage.GetEntryOptionsFromPool()
	op.Expire = c.defaultExpire

	// 保持过期时间不变
	if node != nil {
		if node.expiredMs > 0 {
			op.Expire = time.Duration(node.expiredMs-time.Now().UnixMilli()) * time.Millisecond
			// 如果过期时间小于1秒, 则设置为 1s
			if op.Expire < time.Second {
				op.Expire = time.Second
			}
		} else {
			op.Expire = 0
		}
	}
	// 追加 opts 配置信息, 并覆盖之前的配置信息
	for _, fn := range opts {
		fn(op)
	}
	return op
}

// Scan 获取键对应的值, 并解码到 refVal
//   - refVal 是一个指向具体数据类型的指针, 用于存放反序列化后的数据
//   - 不存在或已经过期或反序列化失败则返回错误
//   - 标量类型直接解析到 refVal
//   - 其他返回数据为 msgpack 自动反序列化后解析到 refVal
func (c *MemoryCache) Scan(key string, refVal any) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if refVal == nil {
		return storage.ErrRefValueIsNil
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	return c._scan(shard, key, refVal)
}
func (c *MemoryCache) _scan(shard *memoryShard, key string, refVal any) (err error) {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if refVal == nil {
		return storage.ErrRefValueIsNil
	}
	node, exists := shard.items[key]
	if !exists || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return storage.ErrKeyNotExists
	}
	// 检查是否过期
	if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
		atomic.AddInt64(&shard.totalMisses, 1)
		shard.moveToBack(node)
		return storage.ErrKeyExpired
	}
	shard.moveToFront(node)
	atomic.AddInt64(&shard.totalHits, 1)

	if node.kind == storage.KindInvalid {
		return storage.ErrKeyKindInvalid
	}

	if node.kind != storage.KindSerializer {
		switch refVal := refVal.(type) {
		case *any:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal = node.value
			return nil
		case **any:
			if *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal = node.value
			return
		case *string:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToString(node.kind, node.value)
			return
		case **string:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToString(node.kind, node.value)
			return
		case *bool:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToBool(node.kind, node.value)
			return
		case **bool:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToBool(node.kind, node.value)
			return
		case *int64:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToInt64(node.kind, node.value)
			return
		case **int64:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToInt64(node.kind, node.value)
			return
		case *int32:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToInt32(node.kind, node.value)
			return
		case **int32:
			if *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToInt32(node.kind, node.value)
			return
		case *int16:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToInt16(node.kind, node.value)
			return
		case **int16:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToInt16(node.kind, node.value)
			return
		case *int8:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToInt8(node.kind, node.value)
			return
		case **int8:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToInt8(node.kind, node.value)
			return
		case *int:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToInt(node.kind, node.value)
			return
		case **int:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToInt(node.kind, node.value)
			return
		case *uint64:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToUint64(node.kind, node.value)
			return
		case **uint64:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToUint64(node.kind, node.value)
			return
		case *uint32:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToUint32(node.kind, node.value)
			return
		case **uint32:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToUint32(node.kind, node.value)
			return
		case *uint16:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToUint16(node.kind, node.value)
			return
		case **uint16:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToUint16(node.kind, node.value)
			return
		case *uint8:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToUint8(node.kind, node.value)
			return
		case **uint8:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToUint8(node.kind, node.value)
			return
		case *uint:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToUint(node.kind, node.value)
			return
		case **uint:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToUint(node.kind, node.value)
			return

		case *float64:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToFloat64(node.kind, node.value)
			return
		case **float64:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToFloat64(node.kind, node.value)
			return
		case *float32:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToFloat32(node.kind, node.value)
			return
		case **float32:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToFloat32(node.kind, node.value)
			return
		case *time.Time:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToTime(node.kind, node.value)
			return
		case **time.Time:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToTime(node.kind, node.value)
			return
		case *time.Duration:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToDuration(node.kind, node.value)
			return
		case **time.Duration:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToDuration(node.kind, node.value)
			return
		case *time.Month:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToMonth(node.kind, node.value)
			return
		case **time.Month:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToMonth(node.kind, node.value)
			return
		case *time.Weekday:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToWeekday(node.kind, node.value)
			return
		case **time.Weekday:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToWeekday(node.kind, node.value)
			return

		case *complex128:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToComplex128(node.kind, node.value)
			return
		case **complex128:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToComplex128(node.kind, node.value)
			return
		case *complex64:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToComplex64(node.kind, node.value)
			return
		case **complex64:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToComplex64(node.kind, node.value)
			return
		case *net.IP:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToIP(node.kind, node.value)
			return
		case **net.IP:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToIP(node.kind, node.value)
			return
		case *[]byte:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToBytes(node.kind, node.value)
			return
		case **[]byte:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToBytes(node.kind, node.value)
			return

			// SetString 集合类型转换
		case *map[string]struct{}:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToSetStringMap(node.kind, node.value)
			return
		case **map[string]struct{}:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToSetStringMap(node.kind, node.value)
			return
			// SetInteger 集合类型转换
		case *map[int64]struct{}:
			if refVal == nil {
				return storage.ErrRefValueIsNil
			}
			*refVal, err = storage.ValueToSetIntMap(node.kind, node.value)
			return
		case **map[int64]struct{}:
			if refVal == nil || *refVal == nil {
				return storage.ErrRefValueIsNil
			}
			**refVal, err = storage.ValueToSetIntMap(node.kind, node.value)
			return
		}
		return storage.ErrKeyKindInvalid
	}
	if node.value == nil {
		return fmt.Errorf("cache: unable to val of type nil to %T", refVal)
	}
	if val, ok := node.value.([]byte); ok {
		return msgpack.Unmarshal(val, refVal)
	}
	return fmt.Errorf("cache: unable to val of type %T to %T", node.value, refVal)
}

// Get 获取键对应的值
//   - 不存在或如果已经过期则返回错误
//   - 存在则返回缓存值:
//   - - 标量类型直接返回 Any 缓存数据值
//   - - 其他返回数据为 msgpack 自动反序列化后的 Any 缓存数据值
func (c *MemoryCache) Get(key string) (any, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	s, err := c._get(shard, key)
	return s, err
}
func (c *MemoryCache) _get(shard *memoryShard, key string) (any, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	node, exists := shard.items[key]
	if !exists || node == nil || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return nil, storage.ErrKeyNotExists
	}
	// 检查是否过期
	if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
		atomic.AddInt64(&shard.totalMisses, 1)
		shard.moveToBack(node)
		return nil, storage.ErrKeyExpired
	}
	shard.moveToFront(node)
	atomic.AddInt64(&shard.totalHits, 1)
	return c._readAny(node)
}
func (c *MemoryCache) _getNode(shard *memoryShard, key string) (*memoryEntry, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	node, exists := shard.items[key]
	if !exists || node == nil || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return nil, storage.ErrKeyNotExists
	}
	// 检查是否过期
	if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
		atomic.AddInt64(&shard.totalMisses, 1)
		shard.moveToBack(node)
		return nil, storage.ErrKeyExpired
	}
	shard.moveToFront(node)
	atomic.AddInt64(&shard.totalHits, 1)
	return node, nil
}

func (c *MemoryCache) _readAny(node *memoryEntry) (any, error) {
	if node.kind == storage.KindNil {
		return nil, nil
	}
	if node.kind == storage.KindInvalid {
		return nil, storage.ErrKeyKindInvalid
	}
	if node.kind != storage.KindSerializer {
		return node.value, nil
	}

	if data, ok := node.value.([]byte); ok {
		var s any
		err := msgpack.Unmarshal(data, &s)
		return s, err
	}
	return nil, storage.ErrValueNotBytes
}

// GetEntry 获取键对应的缓存项副本信息, 如果不存在或已经过期则返回错误
func (c *MemoryCache) GetEntry(key string) (entry *storage.Entry, err error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	// 不存在则设置并返回
	if !exists || node == nil || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return nil, storage.ErrKeyNotExists
	}
	if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
		shard.moveToBack(node)
		atomic.AddInt64(&shard.totalMisses, 1)
		return nil, storage.ErrKeyExpired
	}
	shard.moveToFront(node)
	atomic.AddInt64(&shard.totalHits, 1)

	anyVal, err := c._readAny(node)
	if err != nil {
		return nil, err
	}

	var expire time.Duration = 0
	if node.expiredMs > 0 {
		expire = time.Duration(node.expiredMs-time.Now().UnixMilli()) * time.Millisecond
	}
	return &storage.Entry{
		Key:    node.key,
		Kind:   node.kind,
		Value:  anyVal,
		Size:   node.size,
		Expire: expire,
		Tags:   c.GetKeyTags(key),
	}, err
}

// GetOrSet 获取键对应的值, 如不存在则设置为指定的值
//   - 不存在或如果已经过期则进行设置并返回设置的值
//   - 存在则返回旧值:
//   - - 标量类型直接返回 Any 缓存数据值
//   - - 其他返回数据为 msgpack 自动反序列化后的 Any 缓存数据值
func (c *MemoryCache) GetOrSet(key string, value any, opts ...storage.EntryOptions) (any, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	// 不存在则设置并返回
	if !exists || node == nil || node.isEvicted.Load() {
		if value == nil {
			return nil, storage.ErrValueIsNil
		}
		atomic.AddInt64(&shard.totalMisses, 1)
		err := c._setOptions(shard, key, value, opts...)
		return value, err
	}
	// 过期则设置并返回
	if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
		if value == nil {
			return nil, storage.ErrValueIsNil
		}
		atomic.AddInt64(&shard.totalMisses, 1)
		shard.moveToBack(node)
		err := c._setOptions(shard, key, value, opts...)
		return value, err
	}
	// 存在则解码后返回
	return c._readAny(node)
}

// GetAndSet 获取键对应的旧值并设置新值
//   - 不存在或如果已经过期则返回nil
//   - 存在则返回旧值:
//   - - 标量类型直接返回 Any 缓存数据值
//   - - 其他返回数据为 msgpack 自动反序列化后的 Any 缓存数据值
func (c *MemoryCache) GetAndSet(key string, value any, opts ...storage.EntryOptions) (oldVal any, err error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	if value == nil {
		return nil, storage.ErrValueIsNil
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	oldVal, _ = c._get(shard, key)
	err = c._setOptions(shard, key, value, opts...)
	if err != nil {
		return oldVal, err
	}
	return oldVal, nil
}

// GetAndDelete 获取键对应的值, 并删除该键
//   - 不存在或如果已经过期则返回错误
//   - 存在则返回值:
//   - - 标量类型直接返回 Any 缓存数据值
//   - - 其他返回数据为 msgpack 自动反序列化后的 Any 缓存数据值
func (c *MemoryCache) GetAndDelete(key string) (any, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	s, err := c._get(shard, key)
	if err == nil {
		err = c._delete(shard, key)
	}
	return s, err
}

// GetTags 获取所有Tag标签
func (c *MemoryCache) GetTags() []string {
	tags := make([]string, 0, 1024)
	for _, shard := range c.tagKeys {
		tags = append(tags, shard.GetKeys()...)
	}
	slices.Sort(tags)
	return tags
}

// GetTagKeys 获取指定 Tag 标签对应的所有缓存 Keys 键名
func (c *MemoryCache) GetTagKeys(tag string) []string {
	if tag == "" {
		return []string{}
	}
	return c.getTagKeysShard(tag).GetItems(tag)
}

// GetKeyTags 获取指定键名 Key 对应的所有缓存 Tags 标签
func (c *MemoryCache) GetKeyTags(key string) []string {
	if key == "" {
		return []string{}
	}
	return c.getKeyTagsShard(key).GetItems(key)
}

// Set 设置键值对, 可以通过 EntryOption 设置 Expire, Tag 等选项
//   - key 为空 或 value 为nil 则返回错误
//   - 如缓存 key 已存在且 opts 为空, 则保持过期时间Tags等选项
//   - 如缓存 key 已存在且 opts 不为空, 则更新过期时间Tags等opts选项(原Tag保留, 如有新Tag则追加)
//   - 如缓存 key 不存在且 opts 为空, 则使用默认选项存储数据
//   - 如缓存 key 不存在且 opts 不为空, 则使用opts选项存储数据
func (c *MemoryCache) Set(key string, value any, opts ...storage.EntryOptions) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if value == nil {
		return storage.ErrValueIsNil
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	err := c._setOptions(shard, key, value, opts...)
	shard.mu.Unlock()
	return err
}

// _setOptions 设置键值对, 可以通过 EntryOption 设置 Expire, Tag 等选项
//   - key 为空 或 value 为nil 则返回错误
//   - 如缓存 key 已存在且 opts 为空, 则保持过期时间Tags等选项
//   - 如缓存 key 已存在且 opts 不为空, 则更新过期时间Tags等opts选项(原Tag保留, 如有新Tag则追加)
//   - 如缓存 key 不存在且 opts 为空, 则使用默认选项存储数据
//   - 如缓存 key 不存在且 opts 不为空, 则使用opts选项存储数据
func (c *MemoryCache) _setOptions(shard *memoryShard, key string, value any, opts ...storage.EntryOptions) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	value = storage.EntryValueUnderef(value)
	if value == nil {
		return storage.ErrValueIsNil
	}
	var option *storage.EntryOption
	node, exists := shard.items[key]
	if exists && node != nil && !node.isEvicted.Load() {
		// 已存在缓存数据, 更新缓存数据
		// opts 为空 则保持过期时间不变
		// opts 不为空 则更新过期时间Tags等opts选项(原Tag保留, 如有新Tag则追加)
		shard.moveToFront(node)
		atomic.AddInt64(&shard.totalSize, int64(-node.size))
		option = c.getEntryOptionWithEntry(node, opts...)
		node.Reset()
	} else {
		// 新建节点
		node = GetMemoryEntryFromPool()
		shard.addToFront(node)
		atomic.AddInt64(&shard.totalCount, 1)
		// opts 为空, 则使用默认选项存储数据
		// opts 不为空, 则使用opts选项存储数据
		option = c.getEntryOption(opts...)
	}
	// 回收 option 资源
	defer option.Release()
	// 设置缓存键名
	node.key = key
	// 设置缓存过期时间
	if option.Expire > 0 {
		node.expiredMs = time.Now().UnixMilli() + option.Expire.Milliseconds()
	} else {
		node.expiredMs = 0
	}

	// 编码缓存数据
	node.kind = storage.KindDetect(value)
	if node.kind == storage.KindSerializer {
		var err error
		node.value, err = msgpack.Marshal(value)
		if err != nil {
			return err
		}
		node.size = storage.EntryValueSize(node.kind, key, value)
	} else {
		node.value = value
		node.size = storage.EntryValueSize(node.kind, key, value)
	}

	// 编码同时已自动设置size 完毕后同步节点数据大小
	atomic.AddInt64(&shard.totalSize, int64(node.size))
	if int64(node.size) > shard.maxSize {
		internal.GetLogger().Error("cache: value size is too large of entry max size: "+internal.FormatSize(shard.maxSize),
			slog.String("key", key), slog.String("size", internal.FormatSize(int64(node.size))), slog.Any("value", value))
		return storage.ErrValueTooLarge
	}
	node.isEvicted.Store(false)

	shard.items[key] = node
	// 设置缓存 TAG
	if len(option.Tags) > 0 {
		for _, tag := range option.Tags {
			c.getTagKeysShard(tag).AddKV(tag, key)
			c.getKeyTagsShard(key).AddKV(key, tag)
		}
	}
	// 检查是否需要必须立即清理过期数据释放空间
	if atomic.LoadInt64(&shard.totalSize) > shard.maxSize {
		go shard.Evict()
	}
	return nil
}

// SetWithExists 仅当缓存 Key 键存在时才更新设置值, 返回True表示更新成功
func (c *MemoryCache) SetWithExists(key string, value any, opts ...storage.EntryOptions) (updated bool, err error) {
	if key == "" {
		return false, storage.ErrKeyIsEmpty
	}
	if value == nil {
		return false, storage.ErrValueIsNil
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if exists && node != nil && !node.isEvicted.Load() {
		if node.expiredMs > 0 && time.Now().UnixMilli() >= node.expiredMs {
			return false, storage.ErrKeyExpired
		}
		err = c._setOptions(shard, key, value, opts...)
		return err == nil, err
	}
	return false, storage.ErrKeyNotExists
}

// SetWithNotExists 仅当缓存 Key 键不存在时才设置值, 返回True表示设置成功
func (c *MemoryCache) SetWithNotExists(key string, value any, opts ...storage.EntryOptions) (added bool, err error) {
	if key == "" {
		return false, storage.ErrKeyIsEmpty
	}
	if value == nil {
		return false, storage.ErrValueIsNil
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if !exists ||
		node == nil ||
		node.isEvicted.Load() ||
		(node.expiredMs > 0 && time.Now().UnixMilli() >= node.expiredMs) {
		err = c._setOptions(shard, key, value, opts...)
		return err == nil, err
	}
	return false, storage.ErrKeyIsExists
}

// Incr 原子性地将键对应的值增加1, 并返回新的值
//   - 如果键不存在, 则将原子值设为1 (Set Use Opts)
//   - 如果键存在, 则更新的新值(Set Without Opts)
func (c *MemoryCache) Incr(key string, opts ...storage.EntryOptions) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	return c.IncrBy(key, 1, opts...)
}

// IncrBy 原子性地将键对应的值增加Step步进值, 并返回新的值
//   - 如果键不存在, 则将原子值设为Step (Set Use Opts)
//   - 如果键存在, 则更新的新值(Set Without Opts)
func (c *MemoryCache) IncrBy(key string, step int64, opts ...storage.EntryOptions) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	// 读取缓存值
	node, err := c._getNode(shard, key)
	if err != nil {
		// 缓存不存在: 则将原子值设为 Step
		err := c._setOptions(shard, key, step, opts...)
		return step, err
	}
	// 缓存存在: 则更新后返回新值
	val, err := storage.ValueToInt64(node.kind, node.value)
	if err != nil {
		// 缓存存在但不是 int64 类型: 则返回错误
		return step, err
	}
	val = val + step
	err = c._setOptions(shard, key, val, opts...)
	return val, err
}

// Decr 原子性地将键对应的值减少1, 并返回新的值
//   - 如果键不存在, 则将原子值设为 -1 (Set Use Opts)
//   - 如果键存在, 则更新的新值(Set Without Opts)
func (c *MemoryCache) Decr(key string, opts ...storage.EntryOptions) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	return c.DecrBy(key, 1, opts...)
}

// DecrBy 原子性地将键对应的值减少Step步进值, 并返回新的值
//   - 如果键不存在, 则将原子值设为 -Step (Set Use Opts)
//   - 如果键存在, 则更新的新值(Set Without Opts)
func (c *MemoryCache) DecrBy(key string, step int64, opts ...storage.EntryOptions) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	// 读取缓存值
	node, err := c._getNode(shard, key)
	if err != nil {
		// 缓存不存在: 则将原子值设为 -Step
		err := c._setOptions(shard, key, -step, opts...)
		return -step, err
	}
	// 缓存存在: 则更新后返回新值
	val, err := storage.ValueToInt64(node.kind, node.value)
	if err != nil {
		// 缓存存在但不是 int64 类型: 则返回错误
		return -step, err
	}
	val = val - step
	err = c._setOptions(shard, key, val, opts...)
	return val, err
}

// LoadDo 获取键对应的值, 并反序列化解析后赋值到 refVal
//   - refVal 是一个指向具体类型的指针, 用于存放反序列化后的数据
//   - 缓存存在: 则反序列化解析后赋值到 refVal
//   - 缓存不存在: 则执行 Fn 函数获取查询值后设置为缓存(Set Use Opts), 最后赋值到 refVal
//   - 注意: 请确保 refVal(&T) 的类型和 do() 函数的返回值T类型一致
func (c *MemoryCache) LoadDo(key string, refVal any, do func() (setVal any, err error), opts ...storage.EntryOptions) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if refVal == nil {
		return storage.ErrRefValueIsNil
	}

	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	// 尝试获取缓存值
	if err := c._scan(shard, key, refVal); err == nil {
		return nil
	}
	// 通过 singleflight 执行 do 函数获取缓存值, 并设置到缓存中
	_, err, shared := shard.sfGroup.Do(key, func() (any, error) {
		// 捕获异常
		defer func() {
			if r := recover(); r != nil {
				internal.GetLogger().Error("cache: LoadDo recover with panic", slog.String("key", key), slog.Any("panic", r))
			}
		}()
		// 再次尝试获取缓存值, 防止并发情况下重复执行 do 函数
		if err := c._scan(shard, key, refVal); err == nil {
			return nil, nil
		}
		// 执行 do 函数获取缓存值, 并设置到缓存中
		value, err := do()
		if err != nil {
			return nil, err
		}
		if value == nil {
			return nil, storage.ErrValueIsNil
		}
		err = c._setOptions(shard, key, value, opts...)
		if err != nil {
			return nil, err
		}
		// 共享缓存值, 直接赋值到 refVal
		if err := c._scan(shard, key, refVal); err != nil {
			return nil, err
		}
		return nil, nil
	})
	if err != nil {
		return err
	}
	if shared {
		// 共享缓存值, 直接赋值到 refVal
		if err := c._scan(shard, key, refVal); err != nil {
			return err
		}
	}
	return nil
}

// UpdateFn 更新键对应的值
//   - 如果键不存在, 则执行 Fn 函数设置值并返回设置的默认值(Set Use Opts), 并返回设置的默认值
//   - 如果键存在, 则执行 Fn 函数更新值并返回更新的新值(Set Without Opts), 并返回更新的新值(过期时间/Tags保存不变)
func (c *MemoryCache) UpdateFn(key string, fn func(getVal any, exits bool) (updateVal any, err error), opts ...storage.EntryOptions) (any, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()

	// 捕获 fn 异常
	defer func() {
		if r := recover(); r != nil {
			internal.GetLogger().Error("cache: UpdateFn recover with panic", slog.String("key", key), slog.Any("panic", r))
		}
	}()

	// 尝试获取缓存值, 并执行更新函数
	node, exists := shard.items[key]
	if !exists ||
		node == nil ||
		node.isEvicted.Load() ||
		(node.expiredMs > 0 && node.expiredMs < time.Now().UnixMilli()) {
		// 键不存在, 则执行 Fn 函数设置值并返回设置的默认值(Set Use Opts), 并返回设置的默认值
		value, err := fn(nil, false)
		if err != nil {
			return nil, err
		}
		if value == nil {
			return nil, storage.ErrValueIsNil
		}
		err = c._setOptions(shard, key, value, opts...)
		if err != nil {
			return nil, err
		}
		return value, nil
	}

	// 键存在, 则解码缓存数据后执行更新函数
	anyValue, err := c._readAny(node)

	if err != nil {
		return nil, errors.New("cache: UpdateFn unmarshal error, " + err.Error())
	}
	// 执行更新函数
	value, err := fn(anyValue, true)
	if err != nil {
		return nil, errors.New("cache: UpdateFn call error, " + err.Error())
	}
	if value == nil {
		return nil, errors.New("cache: UpdateFn call error, value is Nil")
	}
	err = c._setOptions(shard, key, value, opts...)
	if err != nil {
		return nil, err
	}
	return value, nil
}

// Expire 设置指定缓存 Key 的存活时间(精度为秒)
func (c *MemoryCache) Expire(key string, duration time.Duration) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if !exists || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return storage.ErrKeyNotExists
	}
	if duration <= 0 {
		node.expiredMs = 0
		shard.moveToFront(node)
		return nil
	}
	if duration < time.Second {
		return storage.ErrSetExpireDuration
	}
	node.expiredMs = time.Now().UnixMilli() + duration.Milliseconds()
	shard.moveToFront(node)
	return nil
}

// ExpireAt 设置指定缓存 Key 的存活时间(精度为秒)
func (c *MemoryCache) ExpireAt(key string, expireAt time.Time) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if !exists || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return storage.ErrKeyNotExists
	}
	if expireAt.Before(time.Now()) {
		return storage.ErrSetExpireAt
	}
	node.expiredMs = max(expireAt.UnixMilli(), time.Now().UnixMilli()+time.Second.Milliseconds())
	shard.moveToFront(node)
	return nil
}

// TTL 获取键的剩余存活时间(精度为秒)
//   - 不存在或如果已经过期则返回-1
//   - 如果设置了永久存活则返回0
func (c *MemoryCache) TTL(key string) time.Duration {
	if key == "" {
		return -1
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if !exists || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return -1
	}
	// 检查是否过期
	if node.expiredMs > 0 {
		nowUnixMilli := time.Now().UnixMilli()
		if node.expiredMs < nowUnixMilli {
			atomic.AddInt64(&shard.totalMisses, 1)
			shard.moveToBack(node)
			return -1
		}
		return time.Duration((node.expiredMs - nowUnixMilli)) * time.Millisecond
	}
	return 0
}

// Kind 获取缓存 Key 的类型信息
//   - 不存在或已经过期则返回错误
func (c *MemoryCache) Kind(key string) (storage.Kind, error) {
	if key == "" {
		return storage.KindInvalid, storage.ErrKeyIsEmpty
	}
	shard := c.getCacheShard(key)
	shard.mu.Lock()
	defer shard.mu.Unlock()
	node, exists := shard.items[key]
	if !exists || node.isEvicted.Load() {
		atomic.AddInt64(&shard.totalMisses, 1)
		return storage.KindInvalid, storage.ErrKeyNotExists
	}
	// 检查是否过期
	if node.expiredMs > 0 {
		nowUnixMilli := time.Now().UnixMilli()
		if node.expiredMs < nowUnixMilli {
			atomic.AddInt64(&shard.totalMisses, 1)
			shard.moveToBack(node)
			return storage.KindInvalid, storage.ErrKeyExpired
		}
	}
	return node.kind, nil
}

// Contains 判断缓存 Key 是否存在, 支持多个键查询, 只要有一个键不存在则返回false
func (c *MemoryCache) Contains(keys ...string) bool {
	if len(keys) == 0 {
		return false
	}
	for _, key := range keys {
		if key == "" {
			return false
		}
		shard := c.getCacheShard(key)
		shard.mu.Lock()
		defer shard.mu.Unlock()
		node, exists := shard.items[key]
		if !exists || node.isEvicted.Load() {
			atomic.AddInt64(&shard.totalMisses, 1)
			return false
		}
		// 检查是否过期
		if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
			atomic.AddInt64(&shard.totalMisses, 1)
			return false
		}
		atomic.AddInt64(&shard.totalHits, 1)
	}
	return true
}

// ContainsSome 判断缓存 Key 是否存在, 支持多个键查询, 如果有一个或多个键存在则返回true
func (c *MemoryCache) ContainsSome(keys ...string) bool {
	if len(keys) == 0 {
		return false
	}
	for _, key := range keys {
		if key == "" {
			continue
		}
		shard := c.getCacheShard(key)
		shard.mu.Lock()
		defer shard.mu.Unlock()
		node, exists := shard.items[key]
		if !exists || node.isEvicted.Load() {
			atomic.AddInt64(&shard.totalMisses, 1)
			return false
		}
		// 检查是否过期
		if node.expiredMs > 0 && time.Now().UnixMilli() > node.expiredMs {
			atomic.AddInt64(&shard.totalMisses, 1)
			return false
		}
		atomic.AddInt64(&shard.totalHits, 1)
		return true
	}
	return false
}

// ContainsTags 检查 Tag 标签是否存在
func (c *MemoryCache) ContainsTags(tags ...string) bool {
	if len(tags) == 0 {
		return false
	}
	for _, tag := range tags {
		if !c.getTagKeysShard(tag).Has(tag) {
			return false
		}
	}
	return true
}

// ContainsSomeTags 检查 Tag 标签是否存在, 支持多个键查询, 如果有一个或多个键存在则返回true
func (c *MemoryCache) ContainsSomeTags(tags ...string) bool {
	if len(tags) == 0 {
		return false
	}
	for _, tag := range tags {
		if c.getTagKeysShard(tag).Has(tag) {
			return true
		}
	}
	return false
}

// ContainsTagKey 检查 Tag/Key 标签对是否存在
func (c *MemoryCache) ContainsTagKey(tag, key string) bool {
	if tag == "" || key == "" {
		return false
	}
	return c.getTagKeysShard(tag).HasKV(tag, key)
}

// Metrics 返回监控指标
func (c *MemoryCache) Metrics() *storage.Metrics {
	var (
		totalSize    int64
		totalCount   int64
		totalHits    int64
		totalMisses  int64
		totalEvicts  int64
		totalExpires int64
	)
	for _, shard := range c.shards {
		totalSize += atomic.LoadInt64(&shard.totalSize)
		totalCount += atomic.LoadInt64(&shard.totalCount)
		totalHits += atomic.LoadInt64(&shard.totalHits)
		totalMisses += atomic.LoadInt64(&shard.totalMisses)
		totalEvicts += atomic.LoadInt64(&shard.totalEvicts)
		totalExpires += atomic.LoadInt64(&shard.totalExpires)
	}
	// 总请求数 = 命中次数 + 未命中次数
	totalRequests := totalHits + totalMisses

	var hitRate, evictionRate, missRate string
	if totalRequests > 0 {
		hitRate = fmt.Sprintf("%.2f%%", float64(totalHits)/float64(totalRequests)*100)
	} else {
		hitRate = "0.00%"
	}
	if totalEvicts > 0 {
		evictionRate = fmt.Sprintf("%.2f%%", float64(totalEvicts)/float64(totalRequests)*100)
	} else {
		evictionRate = "0.00%"
	}
	if totalMisses > 0 {
		missRate = fmt.Sprintf("%.2f%%", float64(totalMisses)/float64(totalRequests)*100)
	} else {
		missRate = "0.00%"
	}

	AverageItemSize := int64(0)
	if totalCount > 0 {
		AverageItemSize = totalSize / totalCount
	}
	return &storage.Metrics{
		MaxSize:         internal.FormatSize(c.maxSize),
		TotalSize:       internal.FormatSize(totalSize),
		TotalCount:      totalCount,
		TotalRequests:   totalRequests,
		TotalHits:       totalHits,
		TotalMisses:     totalMisses,
		TotalEvicts:     totalEvicts,
		TotalExpires:    totalExpires,
		HitRate:         hitRate,
		EvictRate:       evictionRate,
		MissRate:        missRate,
		AverageItemSize: internal.FormatSize(AverageItemSize),
	}
}

// Cleanup 手动清理过期数据
func (c *MemoryCache) Cleanup() error {
	for _, shard := range c.shards {
		shard.Evict()
	}
	return nil
}

// Delete 依据缓存key删除缓存项
func (c *MemoryCache) Delete(keys ...string) error {
	if len(keys) == 0 {
		return nil
	}
	for _, key := range keys {
		if key == "" {
			continue
		}
		shard := c.getCacheShard(key)
		shard.mu.Lock()
		c._delete(shard, key)
		shard.mu.Unlock()
	}
	return nil
}
func (c *MemoryCache) _delete(shard *memoryShard, key string) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	node, exists := shard.items[key]
	if !exists || node == nil {
		return storage.ErrKeyNotExists
	}
	if node.isEvicted.CompareAndSwap(false, true) {
		shard.removeNode(node)
		delete(shard.items, key)
		atomic.AddInt64(&shard.totalCount, -1)
		atomic.AddInt64(&shard.totalSize, int64(-node.size))
		shard.resetNode(node)
		// 删除标签关系
		keyTags := c.getKeyTagsShard(key)
		if tags := keyTags.GetItems(key); len(tags) > 0 {
			for _, tag := range tags {
				keyTags.RemoveKV(key, tag)
				c.getTagKeysShard(tag).RemoveKV(tag, key)
			}
		}
	}
	return nil
}

// DeleteTags 依据缓存Tag标签删除缓存项, 同时tag 标签以及对应的 key <=> tags 和 tag <=> keys 的索引集合数据
func (c *MemoryCache) DeleteTags(tags ...string) error {
	if len(tags) == 0 {
		return nil
	}
	// 删除 tag=>keys 缓存项 及 tag <=> keys 和 key <=> tags 索引的集合数据
	for _, tag := range tags {
		if tag == "" {
			continue
		}
		keys := c.GetTagKeys(tag)
		if len(keys) == 0 {
			continue
		}
		c.Delete(keys...)
	}
	// 删除 tag 标签
	for _, tag := range tags {
		c.getTagKeysShard(tag).Remove(tag)
	}
	return nil
}

// Clear 清空所有数据(同步操作)
func (c *MemoryCache) Clear() error {
	for _, shard := range c.shards {
		shard.Clear()
	}
	for _, shard := range c.tagKeys {
		shard.Clear()
	}
	for _, shard := range c.keyTags {
		shard.Clear()
	}
	return nil
}

// ClearAsync 清空所有数据(异步操作)
func (c *MemoryCache) ClearAsync() error {
	for _, shard := range c.shards {
		go shard.Clear()
	}
	for _, shard := range c.tagKeys {
		go shard.Clear()
	}
	for _, shard := range c.keyTags {
		go shard.Clear()
	}
	return nil
}

// TotalSize 返回当前缓存的总大小(单位: byte)
func (c *MemoryCache) TotalSize() int64 {
	var count int64
	for _, shard := range c.shards {
		count += atomic.LoadInt64(&shard.totalSize)
	}
	return count
}

// TotalCount 返回当前缓存项(Key)的总数量(单位: 个)
func (c *MemoryCache) TotalCount() int64 {
	var count int64
	for _, shard := range c.shards {
		count += atomic.LoadInt64(&shard.totalCount)
	}
	return count
}

// MaxSize 返回当前缓存实例的最大容量(单位: byte)
func (c *MemoryCache) MaxSize() int64 {
	return c.maxSize
}

// MaxEntrySize 获取单个缓存项数据限制的大小(单位: byte)
func (c *MemoryCache) MaxEntrySize() int64 {
	return c.maxEntrySize
}

// StorageType 获取缓存存储驱动类型
func (c *MemoryCache) StorageType() storage.StorageType {
	return storage.StorageMemory
}

// DefaultExpire 获取默认过期时间
func (c *MemoryCache) DefaultExpire() time.Duration {
	return c.defaultExpire
}

// UseLocal 仅使用 Local 缓存进行操作( 通常为 MemoryCache )
//   - 仅在 L2Cache 驱动模式下有效, 其他驱动模式返回自身驱动实例
func (c *MemoryCache) UseLocal() storage.Storager {
	return c
}

// UseRemote 仅仅使用 Remote 进行缓存操作( 通常为 RedisCache )
//   - 仅在 L2Cache 驱动模式下有效, 其他驱动模式返回自身驱动实例
func (c *MemoryCache) UseRemote() storage.Storager {
	return c
}

// LiveState 获取当前缓存实例的运行状态
func (c *MemoryCache) LiveState() storage.LiveState {
	if c.isClosed.Load() {
		return storage.LiveStateShutdown
	}
	// 若内存占用接近最大容量的99%, 则视为异常状态
	if c.TotalSize() > (c.MaxSize() * 99 / 100) {
		return storage.LiveStateFailure
	}
	return storage.LiveStateNormal
}

// IsGlobal 是否为全局缓存实例
func (c *MemoryCache) IsGlobal() bool {
	return c.isGlobal
}

// SetGlobal 设置实例为全局缓存标记
func (c *MemoryCache) SetGlobal() {
	c.isGlobal = true
}
